import {
  ForbiddenException,
  Injectable,
  NotFoundException,
} from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import mongoose, { FilterQuery, Model, Types } from 'mongoose';
import { Group } from '../entities/group.entity';
import { GroupUser } from '../entities/group-user.entity';
import { UpdateGroupDto } from '../dto/group/update-group.dto';

@Injectable()
export class GroupService {
  constructor(
    @InjectModel(Group.name) private groupModel: Model<Group>,
    @InjectModel(GroupUser.name) private groupUserModel: Model<GroupUser>,
  ) {}

  // 获取群列表
  async getGroups(
    pageNum: number = 1,
    pageSize: number = 10,
    keyword?: string,
  ): Promise<{
    total: number;
    groups: Group[];
  }> {
    // 模糊查询
    let idQuery;
    try {
      idQuery = { _id: new mongoose.Types.ObjectId(keyword) };
    } catch {}
    let query: FilterQuery<any> = {};
    if (keyword) {
      query.$or = [
        ...(idQuery ? [idQuery] : []),
        { groupName: { $regex: keyword, $options: 'i' } },
      ];
    }

    // // 获取群数据
    let total = await this.groupModel.countDocuments(query);
    let groups = await this.groupModel.aggregate([
      // 匹配查询条件
      { $match: query },
      // 分页
      { $skip: (pageNum - 1) * pageSize },
      { $limit: pageSize },
      // 添加排序
      { $sort: { _id: -1 } },
      // 查找群组成员
      {
        $lookup: {
          from: 'group_users', // GroupUser 集合的名称
          localField: '_id', // 当前文档的字段
          foreignField: 'groupId', // 目标集合中的字段
          as: 'groupUsers', // 字段名将会出现在结果中
        },
      },
      // 查找群组成员对应的用户信息
      {
        $unwind: '$groupUsers', // 将 groupUsers 数组展开
      },
      {
        $lookup: {
          from: 'users', // User 集合的名称
          localField: 'groupUsers.userId',
          foreignField: '_id',
          as: 'groupUsers.user', // 字段名会出现在结果中
        },
      },
      {
        $unwind: '$groupUsers.user', // 再次展开 user 数组
      },
      {
        $project: {
          _id: 1,
          groupName: 1,
          groupNumber: 1,
          sign: 1,
          imgUrl: 1,
          creatTime: 1,
          userId: 1,
          groupUsers: {
            _id: '$groupUsers.user._id',
            nick: '$groupUsers.user.nick',
            imgUrl: '$groupUsers.user.imgUrl',
            sign: '$groupUsers.user.sign',
          },
        },
      },
      // 重新组合数据
      {
        $group: {
          _id: '$_id',
          groupName: { $first: '$groupName' },
          groupNumber: { $first: '$groupNumber' },
          sign: { $first: '$sign' },
          imgUrl: { $first: '$imgUrl' },
          creatTime: { $first: '$creatTime' },
          userId: { $first: '$userId' },
          groupUsers: { $push: '$groupUsers' },
        },
      },
    ]);
    return { groups, total };
  }

  // 更新群信息
  async updateGroup(
    updateGroupDto: UpdateGroupDto,
  ): Promise<mongoose.UpdateWriteOpResult> {
    const { _id, imgUrl } = updateGroupDto;
    !imgUrl && Object.assign(updateGroupDto, { imgUrl: '/group_pic.png' });
    return await this.groupModel.updateOne({ _id }, { ...updateGroupDto });
  }

  // 移除群成员
  async removeGroupMember(
    groupId: string,
    userId: string,
  ): Promise<mongoose.mongo.DeleteResult> {
    let group = await this.groupModel.findOne({ _id: groupId });
    if (!group) {
      throw new NotFoundException('群聊不存在');
    } else if (group.userId === userId) {
      throw new ForbiddenException('群主不能被移除');
    }
    return await this.groupUserModel.deleteOne({
      groupId: new Types.ObjectId(groupId),
      userId: new Types.ObjectId(userId),
    });
  }
}
